#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include "dragon.h"
using namespace std;
GLint dragonlid;
const int w=32, h=32;
ofstream  out("visibility10.txt");
void DrawStencil()
{
    glPushMatrix();
    glTranslatef(0.0f,0.0f,10.0f);
    glEnable(GL_QUADS);
    glVertex3d(0,0,0);
    glVertex3d(0,w,0);
    glVertex3d(w,w,0);
    glVertex3d(w,0,0);
    glDisable(GL_QUADS);
    glPopMatrix();
}

GLint GenList()
{
    dragonlid = glGenLists(1);
    glNewList(dragonlid, GL_COMPILE);
    DrawDragon();
    glEndList();
    return dragonlid;
}
void DrawDragonList()
{
    glPushMatrix();
    glCallList(dragonlid);
    glPopMatrix();
}
bool flag = false;
void redraw()
{
    static int fbo_camera_v_id=45000, direction = 0;//0为正z，1为-z，2为正x，3为负x，4为正y（x朝上），5为负y
    if(fbo_camera_v_id==50000){
        cout<<"finish visibily";
        if(!flag){
            //out<<"}};"<<endl;
            flag = true;
        }
        return;
    }
    if(fbo_camera_v_id%500==0&&fbo_camera_v_id!=0)
        cout<<fbo_camera_v_id<<endl;
    glClearColor(0   ,   0  ,    0 ,     1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|    GL_STENCIL_BUFFER_BIT);
    glViewport(0,0,w,h);						// Reset The Current Viewport

    glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
    glLoadIdentity();									// Reset The Projection Matrix

    gluPerspective(90, 1.0, 1, 1000);

    glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    switch (direction) {
    case 0:
        gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   0, 0, 1,
                   0, 1, 0);
        direction++;
        break;
    case 1:
        gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   0, 0, -1,
                   0, 1, 0);
        direction++;
        break;
    case 2:
        gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   1, 0, 0,
                   0, 1, 0);
        direction++;
        break;
    case 3:
        gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   -1, 0, 0,
                   0, 1, 0);
        direction++;
        break;
    case 4:
        gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   0, 1, 0,
                   1, 0, 0);
        direction++;
        break;
    case 5:
        {gluLookAt(vertices[fbo_camera_v_id][0], vertices[fbo_camera_v_id][1], vertices[fbo_camera_v_id][2],
                   0, -1, 0,
                   1, 0, 0);
        direction=0;
        fbo_camera_v_id++;}
        break;
    default:
        break;
    }
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    GLfloat gray[] = {0.8, 0.8, 0.8, 1.0 };
    GLfloat light_pos[] = {-10, 10, 10, 1};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,gray);
    glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
    glLightfv(GL_LIGHT0, GL_AMBIENT, gray);
    glEnable(GL_LIGHT0);
    glEnable(GL_STENCIL_TEST);//开模板测试
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS, 0x0, ~0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    DrawStencil();
    glStencilFunc(GL_ALWAYS, 0x0, ~0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
    DrawDragonList();
    char *ste;
    ste = new char [w*w];
    glReadPixels(0,0,w,w,GL_STENCIL_INDEX,GL_UNSIGNED_BYTE,ste);

    /*for(int i=w-1;i>=0;i--){
        if(direction ==0)
            out<<int(ste[i*w+0]);
        else
            out<<", "<<int(ste[i*w+0]);
        for(int j=1;j<w;j++){
            out<<", "<<int(ste[i*w+j]);
        }
    }*/
    if(!ste)
        cout<<"error"<<endl;
    for(int i=w-1;i>=0;i--){
//        if(direction ==1&&i==w-1)
//            out<<int(ste[i*w+0]);
//        else
//            out<<", "<<int(ste[i*w+0]);
        for(int j= 1;j<w;j++){
            out<<int(ste[i*w+j])<<" ";
        }
        out<<endl;
    }
    if(direction==0){
        //out<<"},";
        //out<<endl;
        //out<<"{";
    }
    glDisable(GL_STENCIL_TEST);

    //测试模板的使用
    glutSwapBuffers();
}
void idle()
{
    glutPostRedisplay();
}
void reshape(int width, int height)
{
    if (height==0)										// Prevent A Divide By Zero By
    {
        height=1;										// Making Height Equal One
    }

    glViewport(0,0,w,h);						// Reset The Current Viewport

    glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
    glLoadIdentity();									// Reset The Projection Matrix

    float whRatio = (GLfloat)width/(GLfloat)height;
    gluPerspective(90, whRatio, 1, 1000);

    glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
}
int main (int argc,  char *argv[])
{
    //out<<"int visibility[6][6*32*32]={"<<endl;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE|GLUT_STENCIL);
    glutInitWindowSize(32,32);

    int windowHandle = glutCreateWindow("visibility");
    glewInit();
    //beginCubemap();
    //manager->init();
    glutDisplayFunc(redraw);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    GenList();
    glutMainLoop();
}

